/*
 * @(#)LogPrintlnUtil.java   1.0  2022年3月11日
 * 
 * Copyright (c)	2014-2020. All Rights Reserved.	GuangZhou hhmk Technology Company LTD.
 */
package com.swift.core.log;

import java.util.List;

import com.swift.core.model.data.DataModel;
import com.swift.util.type.TypeUtil;

/**
 * 添加说明
 * 
 * @author zhengjiajin
 * @version 1.0 2022年3月11日
 */
public class LogPrintlnUtil {
    /**
     * 带标题输出
     * @param title
     * @param logTitleList
     * @param dataList
     * @return
     */
    public static <T extends DataModel>  String println(String title,List<LogTitle> logTitleList,List<T> dataList) {
        StringBuilder sb = new StringBuilder();
        if(TypeUtil.isNotNull(title)) {
            sb.append("\n");
            sb.append(title);
            sb.append("\n");
        }
        String table = println(logTitleList, dataList);
        sb.append(table);
        return sb.toString();
    }
    /**
     * 不支持汉字
     * @param logTitleList
     * @param dataList
     * @return
     */
    public static <T extends DataModel> String println(List<LogTitle> logTitleList,List<T> dataList) {
        if(TypeUtil.isNull(logTitleList)) return "";
        StringBuilder sb = new StringBuilder();
        sb.append('\n');
        String title = getTitle(logTitleList);
        sb.append(title).append('\n');
        printSepLine(sb, title);
        if(TypeUtil.isNull(dataList)) return sb.toString();
        for (DataModel data : dataList) {
            for(LogTitle logTitle : logTitleList) {
                sb.append(String.format("%" + logTitle.getLength() + "s", getValue(logTitle, data.getString(logTitle.getValueKey()))));
                sb.append('|');
            }
            sb.delete(sb.length()-1, sb.length());
            sb.append('\n');
        }
        printSepLine(sb, title);
        return sb.toString();
    }
    
    private static String getTitle(List<LogTitle> logTitleList) {
        if(TypeUtil.isNull(logTitleList)) return null;
        StringBuilder sb = new StringBuilder();
        for(LogTitle logTitle : logTitleList) {
            sb.append("%"+logTitle.getLength()+"s|");
        }
        String title = String.format(sb.substring(0, sb.length()-1), gettitleNames(logTitleList));
        return title;
    }
    
    private static Object[] gettitleNames(List<LogTitle> logTitleList) {
        Object[] objs = new Object[logTitleList.size()];
        for(int i=0;i<logTitleList.size();i++) {
            objs[i]=logTitleList.get(i).getTitle();
        }
        return objs;
    }
    
    private static String getValue(LogTitle logTitle,String value) {
        if (value == null) {
            return null;
        }
        if(logTitle.getUnit()!=null) {
            if(LogUnit.K.equals(logTitle.getUnit()) && TypeUtil.isNumber(value)) {
                value=TypeUtil.toString(TypeUtil.toLong(value,0)/1024)+"K";
            }
            
            if(LogUnit.M.equals(logTitle.getUnit()) && TypeUtil.isNumber(value)) {
                value=TypeUtil.toString(TypeUtil.toLong(value,0)/1024/1024)+"M";
            }
            
            if(LogUnit.G.equals(logTitle.getUnit()) && TypeUtil.isNumber(value)) {
                value=TypeUtil.toString(TypeUtil.toLong(value,0)/1024/1024/1024)+"G";
            }
            
            if(LogUnit.PRE.equals(logTitle.getUnit())) {
                double pre = TypeUtil.toDouble(value)*100;
                if(pre<0) return value;
                value=TypeUtil.toString(TypeUtil.toDoubleLimit(pre,2))+"%";
            }
        }
        value=value.replace("\n", "");
        if (value.length() > logTitle.getLength()) {
            if(logTitle.getEndSplit()) {
                return value.substring(0,logTitle.getLength()-3)+"...";
            }else {
                return "..." + value.substring(value.length() - logTitle.getLength() + 3);
            }
           
        } else {
            return value;
        }
    }
    
    private static void printSepLine(StringBuilder sb, String title) {
        title.chars().forEach((c) -> {
            if (c == '|') {
                sb.append('+');
            } else {
                sb.append('-');
            }
        });
        sb.append('\n');
    }

    public enum LogUnit {
        K,M,G,PRE;
    }
    
    public static class LogTitle {
        private String title;
        //表格宽度
        private int length;

        private String valueKey;
        //超出部份省细后部？否则省略前部份
        private boolean endSplit=true;
        
        private LogUnit unit;

        public LogTitle() {
            
        }
        
        public LogTitle(String title,int length,String valueKey) {
            this.title=title;
            this.length=length;
            this.valueKey=valueKey;
        }
        
        public LogTitle(String title,int length,String valueKey,LogUnit unit) {
            this.title=title;
            this.length=length;
            this.valueKey=valueKey;
            this.unit=unit;
        }
        
        public LogTitle(String title,int length,String valueKey,LogUnit unit,boolean endSplit) {
            this.title=title;
            this.length=length;
            this.valueKey=valueKey;
            this.unit=unit;
            this.endSplit=endSplit;
        }
        
        public LogTitle(String title,int length,String valueKey,boolean endSplit) {
            this.title=title;
            this.length=length;
            this.valueKey=valueKey;
            this.endSplit=endSplit;
        }
        
        /**
         * @return the title
         */
        public String getTitle() {
            return title;
        }

        /**
         * @param title
         *            the title to set
         */
        public void setTitle(String title) {
            this.title = title;
        }

        /**
         * @return the length
         */
        public int getLength() {
            return length;
        }

        /**
         * @param length
         *            the length to set
         */
        public void setLength(int length) {
            this.length = length;
        }

        /**
         * @return the valueKey
         */
        public String getValueKey() {
            return valueKey;
        }

        /**
         * @param valueKey
         *            the valueKey to set
         */
        public void setValueKey(String valueKey) {
            this.valueKey = valueKey;
        }

        /**
         * @return the endSplit
         */
        public boolean getEndSplit() {
            return endSplit;
        }

        /**
         * @param endSplit the endSplit to set
         */
        public void setEndSplit(boolean endSplit) {
            this.endSplit = endSplit;
        }

        /**
         * @return the unit
         */
        public LogUnit getUnit() {
            return unit;
        }

        /**
         * @param unit the unit to set
         */
        public void setUnit(LogUnit unit) {
            this.unit = unit;
        }
        
    }
}
